package com.culture.bootdemo.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.culture.bootdemo.common.init.LoadScheduledExecutor;
import com.culture.bootdemo.po.Emo;
import com.culture.bootdemo.common.basevo.Result;
import com.culture.bootdemo.common.exception.BusinessException;
import com.culture.bootdemo.dao.AnswerMapper;
import com.culture.bootdemo.dao.EmoMapper;
import com.culture.bootdemo.utils.*;
import com.culture.bootdemo.model.req.UserReq;
import com.google.common.base.Stopwatch;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StopWatch;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.*;

/**
 * @author ：wen
 * @date ：Created in 2019/8/5 16:42
 * @description：:
 */
@RestController
@Slf4j
@RequestMapping("/test")
public class TestController {
    private static final ThreadLocal<Map<String, Object>> LOCAL_CACHE = new ThreadLocal<>();

    @Autowired
    private AnswerMapper answerMapper;
    @Autowired
    private EmoMapper emoMapper;

    //数组接收 yml文件中，逗号分隔的字符串
    @Value("#{'${demo.list}'.split(',')}")
    private List<String> demoList1;

    @Autowired
    private LoadScheduledExecutor loadScheduledExecutor;

    /**
     * 初始化数据并每个一段时间更新
     *
     * @return
     */
    @GetMapping("/testInit")
    public Result<Object> testInit() {
        List<Integer> sensitiveWordList = loadScheduledExecutor.getSensitiveWordList();
        return Result.builder().data(sensitiveWordList).build();
    }

    /**
     * StopWatch: 计时器
     *
     * @return
     */
    @GetMapping("/stopWatchTest")
    public Result<Object> stopWatch() {
        // 方式一：================
        StopWatch stopWatch = new StopWatch("开始计时一");
        stopWatch.start();
        try {
            Thread.sleep(50);
        } catch (Exception e) {
            e.printStackTrace();
        }
        stopWatch.stop();
        log.info("测试计时器效果一:{}", stopWatch.prettyPrint());

        // 方式二：================
        Stopwatch stopWatch2 = Stopwatch.createStarted();
        try {
            Thread.sleep(1200);
        } catch (Exception e) {
            e.printStackTrace();
        }
        stopWatch2.stop();
        log.info("测试计时器效果二：{}", stopWatch2);

        // 方式三：================
        StopWatch stopWatch3 = new StopWatch("开始计时三");
        stopWatch3.start("任务一");
        try {
            Thread.sleep(50);
        } catch (Exception e) {
            e.printStackTrace();
        }
        stopWatch3.stop();
        log.info("测试计时器效果三----任务一:{}ms", stopWatch3.getTotalTimeMillis());

        stopWatch3.start("任务二");
        try {
            Thread.sleep(2000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        stopWatch3.stop();
        log.info("测试计时器效果三----任务二:{}ms", stopWatch3.getLastTaskTimeMillis());
        return new Result<>(1);
    }

    @GetMapping("insert")
    public Result<Object> insert() {
        Emo emo = emoMapper.selectById(1);
        return Result.builder().data(emo).build();
    }

    /**
     * 数据源如果是orcale的话  sql查询 in 条件超过1000个会报错
     * mybatisplus解决如下：
     *
     * @return
     */
    @GetMapping("getList1000")
    public Result<Object> getList1000() {
        //假设list大小超过1000
        List<Integer> list = new ArrayList<>();

        List<List<Integer>> partitionIdList = Lists.partition(list, 1000);
        LambdaQueryWrapper<Emo> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.nested(wrapper -> {
                    for (List<Integer> item : partitionIdList) {
                        wrapper.or().in(Emo::getId, item);
                    }
                }
        );
        List<Emo> emos = emoMapper.selectList(queryWrapper);
        return Result.builder().data(emos).build();
    }


    /**
     * ThreadLocal
     *
     * @return
     */
    @GetMapping("test2")
    public Result<Object> test2() {
        Map<String, Object> user = new HashMap<>();
        user.put("sessionid", new UserReq(1, "1", "2"));
        LOCAL_CACHE.set(user);
        Map<String, Object> stringObjectMap = LOCAL_CACHE.get();
        Object sessionid = stringObjectMap.get("sessionid");
        LOCAL_CACHE.remove();
        return Result.builder().data(sessionid).build();
    }

    /**
     * threadLocal
     *
     * @param id
     * @return
     */
    @GetMapping("test3")
    public Result<Object> test3(String id) {
        System.out.println("--" + LOCAL_CACHE.get());
        if ("1".equals(id)) {
            throw new BusinessException(-1, "此处是个异常");
        }
        return Result.builder().data(0).build();
    }


    /**
     * 获取二维码
     *
     * @param codeContent
     * @param response
     */
    @GetMapping("getCode")
    public void getCode(String codeContent, HttpServletResponse response) {
        System.out.println("codeContent=" + codeContent);
        try {
            /*
             * 调用工具类生成二维码并输出到输出流中
             */
            QrCodeUtils.createCodeToOutputStream(codeContent, response.getOutputStream());
        } catch (IOException e) {
            log.error("发生错误， 错误信息是：{}！", e.getMessage());
        }
    }


    private static final String QRCODE_KEY = "qrcode_crypto_key_initial";

    /**
     * 生成一个code数字
     *
     * @return
     */
    @GetMapping("getQrcode")
    public String getQrcode() {
        String s1 = DateUtil.formatNow(DateUtil.YMDHMS_STR);
        String idStr = IdWorker.getIdStr();
        String s2 = idStr.length() <= 12 ? idStr : idStr.substring(idStr.length() - 12);
        String preStr = s1 + s2;
        String endStr = Md5Utils.getMD5(preStr + QRCODE_KEY).toLowerCase().substring(0, 6);
        return preStr + endStr;
    }

    /**
     * 校验getQrcode()生成的数字
     *
     * @param code
     * @return
     */
    @GetMapping("checkQrcode")
    public boolean checkQrcode(String code) {
        if (StringUtils.isBlank(code)) {
            return false;
        }
        String preStr = code.substring(0, 26);
        String endStr = code.substring(26);
        String substring = Objects.requireNonNull(Md5Utils.getMD5(preStr + QRCODE_KEY)).toLowerCase().substring(0, 6);
        if (endStr.equals(substring)) {
            return true;
        }
        return false;
    }

    @GetMapping("testHttp")
    public void testHttp(Long custId) {
        String url = "http://10.4.12.127:8070/account/queryCustNocash";
        Map<String, Object> params = new HashMap<>();
        params.put("partner", "1300000000");
        params.put("custId", custId);

        HttpClientUtil httpClientUtil = new HttpClientUtil();
        String s = httpClientUtil.sendHttpGet(url, params);
        log.info("http返回结果:{}", s);
    }


    /**
     * 反射：根据字段名获取字段属性
     */
    public static void test6() {
//        BeanUtil.getFieldValue()
    }

    /**
     * MessageFormat.format
     */
    public static void test7() {
        Integer shopId = 12;
        String code = "cote";
        String format = MessageFormat.format("shopConfig:shopParamValue:{0,number,##}_{1}", shopId, code);
        String format1 = MessageFormat.format("shopConfig:shopParamValue:{0}_{1}", shopId, code);
        System.out.println(format);
        System.out.println(format1);
        String value = MessageFormat.format("oh, {0,number,#.###} is good num", Double.valueOf("3.1415"));

        System.out.println(value);  // 输出：oh, 3.1 is good num
    }

    public static void main(String[] args) {
        test7();
    }
}
